--
-- Author:      feilong
-- DateTime:    2019-09-4 15:57:48
-- Description: 游戏主逻辑

local skynet = require("skynet")
local Timer = require("Timer")
local FSM = require("FSM")
local reason = require("reason")
local constant = require("constant")

--全局变量本地化
local math_floor = math.floor
local math_random = math.random
local table_insert = table.insert
local math_abs = math.abs

local DeskBase = import("DeskBase")
local Desk = class("Desk",DeskBase)

--构造函数
function Desk:ctor()
	self.super:ctor()
	--https://blog.csdn.net/bigcat133/article/details/46374357
	--极度稀疏数组不输出nil
	-- cjson.encode_sparse_array(true)
	
end

----------------------------------------------------------------------------------------------
---------游戏
---------------------------------------------------------------------------------------------- 
function Desk:start()
	dbglog("___起动百家乐游戏___")
	self.super.start(self) --基础的对象里在里面有初始化的了
	--数据初始化
	self:init()
	self.service_closed = nil --服务已关闭
	--状态时间
	self.state_time = {	
		rest = 1,		--休息时间		
		start = 1,		--开始	
		gameover = 20, 	--结算时间
		bet = 15, 		--下注
		stop_bet = 1,   --结束下注
	}
	--游戏状态
	--state1 --eventName --state2 --callback
	self.state_list = {		
		{"start", 		"to_start_bet",			"bet", 				function() self:onBet() end },		
		{"gameover", 	"to_rest", 				"rest", 			function() self:onRest() end },
		{"rest", 		"to_start", 			"start", 			function() self:onStart() end },			
		{"bet",			"to_stop_bet", 			"stop_bet", 		function() self:onStopBet() end },	
		{"stop_bet", 	"to_gameover",			"gameover", 		function() self:onGameOver() end },
	}
	self.fsm = FSM.new(self.state_list) --状态机
	self.timer = Timer.new() --定时器

	dbglog("___起动机器人_1__")
	--起动机器人
    self.robot_manager:start()
    self.bairen_desk:specialRobotSitdown()
	dbglog("___游戏桌子起完成_____")

	--启动状态机
	self.fsm:set("rest")
	self:changeState("to_start")

	return true
end

-------------------------------------------------------------------------------
-- private
-------------------------------------------------------------------------------

--初始化
function Desk:init()

	--位置id 1闲 2和 3庄 4闲对 5庄对
	self.pool_name = {
		player = 1,
		tie = 2,
		banker = 3,
		player_pairs = 4,
		banker_pairs = 5,
	}
	self.bead = {
		win_id = nil, --1闲 2和 3庄
		pair_id = nil, --1无 2闲对 3庄对
	}
	self.cur_round = 0 --局数 (72局后清数据)
	self.pool_all_bet = {} --各个池已下注总分
	self.pool_user_bet = {} --各池玩家的下注总分
	self.pool_rate = {1,8,1,11,11} --各池赔率 1闲 2和 3庄 4闲对 5庄对
	self.player_cards = {} --闲牌
	self.banker_cards = {} --庄牌	
	self.max_pool_id = 5 --下注位置个数
	self.bet_list_name = "bjl_bet_list"

	self.all_bet_chip = 0 --总下注
	self.win_pool_id = {} --当前局赢的池id	
	self.user_bet_list = {} --玩家总下注	
	self.user_last_bet = {} --玩家上次各池下注数，用于重复下注
	self.user_win_chip = {} --玩家输赢币，算服务费		
	self.win_pool_list = {} --赢的id历史记录列表 存放 self.bead 对象
	self.system_money_cost = 0 --全局总输赢, 不算服务费


	self.bet_user_list = {} --下注过的玩家列表
	self.real_bet_chip = 0 --真人总下注
	self.real_pool_bet = {} --各池真人下注总额

	------------牌局记录--------------
	self.win_pool_total_chip = {} --每一个池的总输赢情况
	self.win_pool_chip = {} --每一个池的真玩家总输赢情况
	self.win_pool_user_chip = {} --每一个池的真玩家各输赢情况
	self.pool_free_bet = {} --各池免佣下注额	
	self.loser_list = {} --输的玩家
	self.winner_list = {} --赢的玩家
	self.start_time = 0 --开始时间
	self.end_time = 0 --结束时间
	self.bet_user_num = 0 --下注人数
	self.win_pool_free_list = {} --各池服务费
	------------流水记录--------------
	self.win_chip_list = {} --各玩家所赢的金币，不算服务费
	self.win_free_list = {} --各玩家所交的服务费
	
	self.system_result = 0 --库存控制开的结果
	self.control_uid = nil --控制的个人
	self.system_send_award = false --获得奖励库存
	self.control_result = 0  --系统控制结果 0控制成功 1系统赢钱 2随机

	--开始是给假的记录数据
	self.cur_round = math_random(8, 60)
	local tb = {1,3}
	for i=1, self.cur_round do 
		local pair_id = math_random(0, 40)
		if pair_id > 3 then 
			pair_id=0
		end
		local win_id = math_random(1, 20)
		if win_id > 3 then 
			win_id = tb[math_random(1, 2)]
		end
		local bead = {win_id=win_id, pair_id=pair_id}
		table_insert(self.win_pool_list, bead)	
	end

	self:reset()	
end

--重置数据
function Desk:reset()
	self.player_cards = {} --闲牌
	self.banker_cards = {} --庄牌
	self.user_win_chip = {} --玩家输赢币，算服务费	
	self.win_chip_list = {} --各玩家所赢的金币，不算服务费	
	self.win_pool_id = {} --当前局赢的池id
	self.user_bet_list = {} --玩家总下注

	self.win_free_list = {} --各玩家所交的服务费
	self.win_pool_free_list = {} --各池服务费
	self.system_money_cost = 0 --总输赢
	self.win_pool_total_chip = {} --每一个池的输赢情况
	self.win_pool_chip = {} --每一个池的真玩家输赢情况
	self.win_pool_user_chip = {}
	self.loser_list = {} --输的玩家
	self.winner_list = {} --赢的玩家	
	self.bet_user_num = 0 --下注人数
	self.real_bet_chip = 0 --真人总下注
	self.pool_free_bet = {} --各池免佣下注额

	self.system_result = 0 --库存控制开的结果
	self.control_uid = nil --控制的个人	
	self.system_send_award = false --获得奖励库存
	self.control_result = 0  --系统控制结果 0控制成功 1系统赢钱 2随机
	--玩家自身状态
	-- self.user_manager:setAllUserValue("playing", false)
	-- self.user_manager:setAllUserValue("beted", false)
	--清下注位置数据
	for i=1,self.max_pool_id do 
		self.pool_all_bet[i] = 0
		self.pool_user_bet[i] = {}
		self.real_pool_bet[i] = 0 --各池真人下注总额
	end
	self.user_last_bet = {}

	self.rule:shuffle() --洗牌
end


-------------------------------------------------------------------------------
-- callback
-------------------------------------------------------------------------------
--玩家进入消息回调 
function Desk:enterReqCallback(uid, fd, msg)
    local res = self:getEnterInfo(uid) --桌子状态信息
    -- print("===桌子状态信息======rsp_enter", res)
    local user = self.user_manager:getUser(uid)
	local can_bet_list = self:getCanBetList(self.bet_list_name, user:getCoins())
	user:setCanBetList(can_bet_list)
    return res
end

--离线回调
function Desk:disconnectCallback(uid)

    return true
end

--离开桌子
function Desk:leaveReqCallback(uid)
	--站起
	--从user_manager中删除
	--发送桌子信息变化到zoneserver
	return true
end



-------------------------------------------------------------------------------
-- 状态
-------------------------------------------------------------------------------

--休息
function Desk:onRest()
	dbglog("____baijiale__onRest")

	--重置数据
	self:reset()
	self:removeDisconnect()	--删除离线的玩家
	local user_list = self.user_manager:getUserList()
	for uid, user in pairs(user_list) do 
		if user:isPlayer() then 
			if not user:getBeted() then 
				--不下注的次数超过5次就踢出桌子
				local no_bet_count = user:getNoBetCount()
				user:setNoBetCount(no_bet_count + 1)			
			    if no_bet_count == 4 then --提示玩家			        
			        self:sendToUser(uid, 'table.NTF_TIPS', {type=0, content = constant.BR_NO_BET_TIP })		        
			    end   
			    if no_bet_count == 6 then 		    	
			        self:kickUser(uid) --踢走			
			    end		      			
			end

			--结算后金币不足坐下条件，需要把他站起
			self:checkStandUpUser(uid)
		end
		user:setInitCoins(user:getCoins()) --游戏开始下注时所拥有的金币值
		user:setPlaying(false)
		user:setBeted(false)
		user:setCurBet(0)		
	end
	self.room_config:reload() --配置加载	
	self:ntRest()
	self:checkServiceClose() --每局休息时检查是否已关服	
    self.robot_manager:loadRobot() --机器人加载
    self.bairen_desk:specialRobotSitdown()    
    
	local callback = function ( ... )			
		self:changeState("to_start")		
	end
	self:setTimer(self.state_time.rest, callback)


end

--开始
function Desk:onStart()
	dbglog("_____baijiale__onStart")			

	--局数
	self.cur_round = self.cur_round + 1
	if self.cur_round == 73 then --清局记录
		self.win_pool_list = {}		
		self.cur_round = 1
	end	
	--设置在线玩家开始
	self.user_manager:setAllUserValue("playing", true)
	self.robot_manager:setTotalCoins()
	self:ntStart()
	--开始下注
	self.start_time = os.time()	
	local callback = function ()
		--停止下注		
		self:changeState("to_start_bet")
	end
	self:setTimer(self.state_time.start, callback)

end

--下注
function Desk:onBet()
	self:ntBet()
	local callback = function ()
		--停止下注		
		self:changeState("to_stop_bet")
	end
	self:setTimer(self.state_time.bet, callback)
end

--停止下注
function Desk:onStopBet()
	self:ntStopBet()
	local callback = function ()
		--停止下注		
		self:changeState("to_gameover")
	end
	self:setTimer(self.state_time.stop_bet, callback)
end

--赢的筹码服务费计算
function Desk:getServiceRate(win_id, user)
	--免佣与传统的不同是开庄时，赔率不同	
	if win_id ~= self.pool_name.banker then 
		return 0
	end	
	local rate_type = user:getRateType()
	if rate_type==0 then --传统抽水率
		return 0.05
	end	
	if self.rule:getPoint(self.banker_cards) == 6 then 
		return 0.5 --免佣开6时赔率
	end
	--免佣抽水率
	return 0
end

--结算
function Desk:onGameOver()
	dbglog("_____baijiale___onGameOver")
	--庄赢 传统抽水5% 免佣6点只赔一半
	--和赢退回闲，庄上的金币
    self.end_time = os.time()

    -- local player_cards, banker_cards = self.rule:getPlayAndBankCards()
    -- self.player_cards = player_cards
    -- self.banker_cards = banker_cards
    --取得一个结果的牌
    self:getResult()
    --结客户端的数据
    local data = {
    	left_time = self.state_time.gameover,    	
        player_cards = self.player_cards,
        banker_cards = self.banker_cards,     
        bet_result_list = {},	--各个玩家结算结果 
    }
    local win_pools = {} --赢的池
	--大小结果
	local win_id = self.rule:compareCard(self.player_cards,self.banker_cards)
	win_pools[win_id] = true
	local bead = {win_id=win_id, pair_id=0}
	table_insert(self.win_pool_list, bead)	--开奖位置
	local play_is_pair = false
	local bank_is_pair = false
	if self.rule:existPair(self.player_cards) then --闲对子
		win_pools[self.pool_name.player_pairs] = true
		play_is_pair = true
		bead.pair_id = 1 
	end
	if self.rule:existPair(self.banker_cards) then  --庄对子
		win_pools[self.pool_name.banker_pairs] = true
		bank_is_pair = true
		bead.pair_id = 2
	end
	if play_is_pair and bank_is_pair then 
		bead.pair_id = 3
	end
	self.win_pool_id = win_pools
	data.win_id = win_id --珠盘路 1闲 2和 3庄
	data.win_pair = bead.pair_id --珠盘路 0无 1闲对 2庄对 3闲庄都是对子

	local total_free = 0 --总的服务费
	--有下注过的
	for uid, _ in pairs(self.user_bet_list) do  
		local user = self.user_manager:getUser(uid)
		self.user_win_chip[uid] = 0 --所赢的币 有下注的返回
		self.win_chip_list[uid] = 0 --输赢的币 无下注的返回
		self.win_free_list[uid] = 0

		local pool_result_list = {}					
		local pool_bet = nil
		for pool_id=1, self.max_pool_id do --每个池是玩家是否有下注
			pool_bet = self.pool_user_bet[pool_id][uid] or 0 --下注额

			self.win_pool_total_chip[pool_id] = self.win_pool_total_chip[pool_id] or 0			
			self.win_pool_chip[pool_id] = self.win_pool_chip[pool_id] or 0
			self.win_pool_user_chip[pool_id] = self.win_pool_user_chip[pool_id] or {}
			self.win_pool_user_chip[pool_id][uid] = 0
			self.win_pool_free_list[pool_id] = self.win_pool_free_list[pool_id] or {}
			self.win_pool_free_list[pool_id][uid] = 0
			if pool_bet > 0 then --池有下注				
				local win_chip = 0 
				local win_free = 0 --服务费
				self.win_chip_list[uid] = self.win_chip_list[uid] or 0 --无下注的返回
				if win_pools[pool_id] then --有赢币
					win_chip = math_floor(pool_bet*(1 + self.pool_rate[pool_id]))
					win_free = math_floor(pool_bet * self:getServiceRate(pool_id, user))
					win_chip = win_chip - win_free
					self.win_chip_list[uid] = self.win_chip_list[uid] + pool_bet*self.pool_rate[pool_id]
					self.win_free_list[uid] = self.win_free_list[uid] + win_free
					self.win_pool_free_list[pool_id][uid] = win_free

					self.win_pool_total_chip[pool_id] = self.win_pool_total_chip[pool_id] + pool_bet*self.pool_rate[pool_id]
					if user:isPlayer() then 
						self.win_pool_chip[pool_id] = self.win_pool_chip[pool_id] + pool_bet*self.pool_rate[pool_id]
						self.win_pool_user_chip[pool_id][uid] = self.win_pool_user_chip[pool_id][uid] + pool_bet*self.pool_rate[pool_id]
					end
				else--输了
					self.win_chip_list[uid] = self.win_chip_list[uid] - pool_bet
					self.win_pool_total_chip[pool_id] = self.win_pool_total_chip[pool_id] - pool_bet
					if user:isPlayer() then 
						self.win_pool_chip[pool_id] = self.win_pool_chip[pool_id] - pool_bet
						self.win_pool_user_chip[pool_id][uid] = self.win_pool_user_chip[pool_id][uid] - pool_bet
					end						
				end
				self.user_win_chip[uid] = self.user_win_chip[uid] + win_chip --有下注的返回
				if win_chip > 0 then 
					local pool_result = {
						side = pool_id,
						result_coins = win_chip,
					}
					table_insert(pool_result_list, pool_result)
				end
			
			end
		end			
		--服务费
		local pay_fee = self.win_free_list[uid]		
		--开和，返回闲、庄金币
		if win_id == self.pool_name.tie then 
			local pools = {1, 3} --闲庄
			for _, pool_id in pairs(pools) do
				local pool_bet = self.pool_user_bet[pool_id][uid] or 0
				if pool_bet > 0 then 
					self.user_win_chip[uid] = self.user_win_chip[uid] + pool_bet
					self.win_chip_list[uid] = self.win_chip_list[uid] + pool_bet
					self.win_free_list[uid] = 0 --开和服务费为0
					self.win_pool_total_chip[pool_id] = self.win_pool_total_chip[pool_id] + pool_bet
					if user:isPlayer() then 
						self.win_pool_chip[pool_id] = self.win_pool_chip[pool_id] + pool_bet
						self.win_pool_user_chip[pool_id][uid] = self.win_pool_user_chip[pool_id][uid] + pool_bet
					end							
				end
				local bet_chip = self:getPoolUserBet(pool_id, uid)
				if bet_chip > 0 then 
					local pool_result = {
						side = pool_id,
						result_coins = bet_chip,
					}
					table_insert(pool_result_list, pool_result)			
				end		
			end								
		end

		--总体输赢
		if self.win_chip_list[uid] >= 0 then 
			--增加赢的局数
			user:addWinCount()	
			user:setLatelyWin(true)	--最近20局	
		    --输赢记录列表
		    if user:isPlayer() then 
			    table_insert(self.winner_list, {uid = uid, left_score = user:getCoins(), add_score = self.win_chip_list[uid]-pay_fee, 
	                pay_fee = pay_fee, is_robot = user:isRobot()})
		   	end
		else
			if user:isPlayer() then 
			    table_insert(self.loser_list, {uid = uid, left_score = user:getCoins(), add_score = self.win_chip_list[uid]-pay_fee, 
	                pay_fee = pay_fee, is_robot = user:isRobot()})
			end

		    user:setLatelyWin(false) --最近20局
		end
		--有赢币
		local coins = self.user_win_chip[uid] 
		if coins > 0 then
			--修改数据库
	        local ret = self:addChip(uid, coins + pay_fee, reason.WIN_COIN)
	        self:reduceChip(uid, pay_fee, reason.PAY_FEE)       			
	        --对局广播
	        self:sendRealHorseMessage(uid, coins, constant.BROADCAST_IDS.BIDS_BJL)   				    
		    --服务费记录
		    self:addFreeChip(uid, self.win_free_list[uid], reason.PAY_FEE)
		    --这里先通知每个人自身金币发生变化		    
			self:ntMoneyChangeToHall(uid, user:getCoins(), constant.MONEY_CHANGED_REASON.HBSL_ROB)	
		end

		--有下注过
		local user_result = {
			uid = uid,
			position = user:getSeatId(), --=0表示没有位置，=1...6表示对应的位置
			result_coins = self.user_win_chip[uid] - self:getUserBet(uid), --下注前后总的输赢
			side_result = pool_result_list, --每一个区域的输赢情况
			curr_coins = user:getCoins(), --当前的金币，加上输赢后的结果
		}
		table_insert(data.bet_result_list, user_result)
		self:winLoseWater(user, self.user_bet_list[uid], self.win_chip_list[uid], pay_fee)
	    local bet_coins = self.user_bet_list[uid]
	    local produce = self.win_chip_list[uid] + self.user_bet_list[uid]
	    local win_lose = self.win_chip_list[uid] - pay_fee
	    local free = pay_fee
	    self:sendSummary(uid, bet_coins, produce, win_lose, free)

		--今天玩家流水
		self:addPlayerWater(user, self.win_chip_list[uid])
		--输赢流水
		self:loseWinCoins(user, coins)
		self:checkCaiShen(user, self.win_chip_list[uid] - pay_fee)
		--全局总输赢
		if user:isPlayer() then 
			self.system_money_cost = self.system_money_cost - self.win_chip_list[uid]
			total_free = total_free + pay_fee
		end

	end

	

	dbglog("________gameover__", data)
	--把输赢发送到好友服
	self:sendLoseWinToFriendServer(self.system_money_cost + total_free)
	--库存更新
	self:updateStore()
	--牌局记录
	self:writeCardRecord()	
	--通知客户端
	self:ntGameOver(data)	

	self.user_manager:setAllUserValue("beted", false) --标记所有玩家为没有下注, 好让机器人离桌
	local callback = function ()
		--休息		
		self:changeState("to_rest")
	end
	self:setTimer(self.state_time.gameover, callback)
	
	
end

-------------------------------------------------------------------------------
-- 推送消息
-------------------------------------------------------------------------------
function Desk:ntRest()
    self:sendToAllUser('baijiale.NTF_REST',{
        left_time = self.state_time.rest,
    })	
end
function Desk:ntStart()
    self:sendToAllUser('baijiale.NTF_START',{
        left_time = self.state_time.start,
    })
	dbglog("__________ps_ntStart", data)
end
function Desk:ntBet()	
    self:sendToAllUser('baijiale.NTF_START_BET',{
        left_time = self.state_time.bet,
    })
end
function Desk:ntStopBet()	
    self:sendToAllUser('baijiale.NTF_STOP_BET',{
        left_time = self.state_time.stop_bet,
    })
end
function Desk:ntGameOver(data)	
    -- required uint32 left_time               = 2; //操作时间     
    -- repeated uint32 win_pools               = 3; //赢的池id 1闲 2和 3庄 4闲对 5庄对   
    -- required string win_chip                = 4; //自己赢的筹码数  
    -- repeated PlayerInfo seat_player         = 5; //座位上信息	
    self:sendToAllUser('baijiale.NTF_GAMEOVER', data)
end



---------------------------------------------------------------------------------------------------------



-- private
---------------------------------------------------------------------------------------------------------
--取桌子配置
function Desk:getConfig(user)
	-- bet_time = 5, --下注时间
	-- --个人限红
	-- person_limit = {1,10000}, 
	-- --区域限红
	-- play_limit = 10000, --闲
	-- bank_limit = 10000, --庄
	-- tie_limit = 10000, --和
	-- play_pair_limit = 10000, --闲对
	-- bank_pair_limit = 10000, --庄对
	-- --池限红
	-- bank_play_limit = 15000, --庄、闲差
	-- tie_total_limit = 18000, --和总值
	-- bank_pair_total_limit = 18000, --庄对总值
	-- play_pair_total_limit = 18000, --闲对总值
  	local room_data = self.room_config:getRoomData()
	return{
		person_limit = room_data.person_limit,
		play_limit = room_data.play_limit,
		bank_limit = room_data.bank_limit,
		tie_limit = room_data.tie_limit,
		play_pair_limit = room_data.play_pair_limit,
		bank_pair_limit = room_data.bank_pair_limit,
		bank_play_limit = room_data.bank_play_limit,
		tie_total_limit = room_data.tie_total_limit,
		bank_pair_total_limit = room_data.bank_pair_total_limit,
		play_pair_total_limit = room_data.play_pair_total_limit,
	    chip_list = self:getCanBetList(self.bet_list_name, user:getCoins()), --下注筹码列表 {100,1000,5000,10000,50000}
	    sitdown_chip = self.room_config:getSitdownCoin(), --坐下需要的金币    
	    need_chip_min = self.room_config:getMinBet(), --最少携带金这么多币量才可以下注
	}
end

--大厅牌中需要的状态
function Desk:getHallStateNum()
    --状态 1修息 2下注 3结算 (每个游戏要自己处理转换)
    --子游戏重写
	-- start
	-- gameover
	-- rest
	-- bet
	-- stop_bet    
    local state = self:getState()
    local state_tb = {
    	start = 1,
    	rest = 1,
    	bet = 2,
    	stop_bet = 3,
    	gameover = 3,
    }
    return state_tb[state]
end

--大厅牌中需要的状态总时间
function Desk:getHallStateTotalTime()   
    local state = self:getState()
    local time_tb = {
    	self.state_time.rest + self.state_time.start,
    	self.state_time.bet,
    	self.state_time.stop_bet + self.state_time.gameover,
    }
    return time_tb
end
function Desk:getHallStateLeftTime()   
	self:getLeftTime()
end

--取下注池信息
function Desk:getPoolList(uid)
	local poolList = {}
	for pool_id=1, self.max_pool_id do 
		local pool = {}
		pool.pool_id = pool_id
		pool.all_bet = self.pool_all_bet[pool_id]
		pool.my_bet = self.pool_user_bet[pool_id][uid]
		pool.rate = self.pool_rate[pool_id] --赔率	
		table_insert(poolList,pool)
	end	
	return poolList
end

--桌子状态信息
function Desk:getEnterInfo(uid)

    local seated_list = {}
    local user = self.user_manager:getUser(uid)
    --有座位的玩家
    local seat_users = self.user_manager:getSeatUsers()
    for _, user in pairs(seat_users) do
    	local info = user:getClientInfo()
        table_insert(seated_list, info)    
    end
    local win_id_list = {} --每场赢列表（牌路）1闲 2和 3庄
    local win_pair_list = {} --每场对子列表
    for k, v in pairs(self.win_pool_list) do 
    	table_insert(win_id_list, v.win_id)
    	table_insert(win_pair_list, v.pair_id)
    end
  
    local enter_info = {        
        config = self:getConfig(user), --配置
        seated_list = seated_list, --有座位的玩家列表
		bet_pool_list = self:getPoolList(uid), --下注池
		all_bet_chip = self.all_bet_chip, --总注
		win_id_list = win_id_list, --每场赢列表（牌路）1闲 2和 3庄
		win_pair_list = win_pair_list, 
		player_cards = self.player_cards,
		banker_cards = self.banker_cards,
		left_time = self:getLeftTime(),
		online_num = self.user_manager:getUserNum(),
		state = self:getStateNum(), --桌子状态 
		room_name = self.room_config:getRoomName(), --桌子名
		desk_type = user:getRateType(), --赔付类型
    }

    dbglog("__222222222222_1__enter_info___",  enter_info)
    return {
        game_type = self.game_type,
        table_type = self.table_type,
        baijiale_enter_info = enter_info,
    }
end

--玩家下注
function Desk:setUserBet(user, bet_chip, pool_id)
	local uid = user:getUid()
	--各池玩家的下注总分
	self:addPoolUserBet(pool_id, uid, bet_chip)

	--各个池已下注总分
	self.pool_all_bet[pool_id] = self.pool_all_bet[pool_id] + bet_chip
	--玩家总下注
	if not self.user_bet_list[uid] then 
		self.user_bet_list[uid] = 0 --玩家总下注
	end
	self.user_bet_list[uid] = self.user_bet_list[uid] + bet_chip
	--总注
	self.all_bet_chip = self.all_bet_chip + bet_chip	
	if user:getRateType()==1 then --免佣
		self.pool_free_bet[pool_id] = self.pool_free_bet[pool_id] or 0
		self.pool_free_bet[pool_id] = self.pool_free_bet[pool_id] + bet_chip
	end
	if not user:getBeted() then 
		self.bet_user_num = self.bet_user_num + 1
	end
	if user:isPlayer() then 
		self.real_bet_chip = self.real_bet_chip + bet_chip --真人总下注
		self.real_pool_bet[pool_id] = self.real_pool_bet[pool_id] + bet_chip --各池真人下注总额
	end

end

--各个池已下注总分
function Desk:getPoolAllBet(pool_id)
	return self.pool_all_bet[pool_id] or 0 
end

--各池玩家的下注总分
function Desk:getPoolUserBet(pool_id, uid)
	if not self.pool_user_bet[pool_id] then 
		self.pool_user_bet[pool_id] = {}
	end
	return self.pool_user_bet[pool_id][uid] or 0 
end

function Desk:addPoolUserBet(pool_id, uid, bet_chip)
	if not self.pool_user_bet[pool_id] then 
		self.pool_user_bet[pool_id] = {}
	end
	if not self.pool_user_bet[pool_id][uid] then 
		self.pool_user_bet[pool_id][uid] = 0
	end
	self.pool_user_bet[pool_id][uid] = self.pool_user_bet[pool_id][uid] + bet_chip
end

--玩家的下注总分
function Desk:getUserBet(uid)
	return self.user_bet_list[uid] or 0 
end

--牌局记录
function Desk:writeCardRecord()
    local side_list = {} --池信息
   	local user_list = self.user_manager:getRealBetUsers() --下过注的真人
    for pool_id=1, self.max_pool_id do 
	    local player_bet_list = {} --玩家下注列表
	    local player_win_list = {} --玩家盈余列表    	
	    local player_bet_coins = 0 --玩家总下注
    	for _, user in pairs(user_list) do 
    		local uid = user:getUid()
    		local bet_num = self:getPoolUserBet(pool_id, uid)
    		if bet_num>0 then --0=传统，1=免佣
    			local bet_info = {
    				uid = uid	    			
	    		}	    		
	    		if user:getRateType() == 0 then 
	    			bet_info.bet_coins_commission = bet_num
	    		else
	    			bet_info.bet_coins_not_commission = bet_num
	    		end
	    		table_insert(player_bet_list, bet_info)

	    		--玩家盈余列表
	    		local win_info = {uid=uid}
	    		if user:getRateType() == 0 then --传统方式
	    			win_info.win_coins_commission = self.win_pool_user_chip[pool_id][uid] --传统方式赢
	    			win_info.teefee_commission = self.win_pool_free_list[pool_id][uid] --服务费
	    		else
	    			win_info.win_coins_not_commission = self.win_pool_user_chip[pool_id][uid]
	    			win_info.teefee_not_commission = self.win_pool_free_list[pool_id][uid]
	    		end
	    		table_insert(player_win_list, win_info)	    		
	    		player_bet_coins = player_bet_coins + self:getPoolUserBet(pool_id, uid) 	    			    		
    		end

    	end
    	local pool_free_bet = self.pool_free_bet[pool_id] or 0 --免佣下注
    	local pool_info = {} --玩家输赢详情
    	pool_info.player_bet_list = player_bet_list
    	pool_info.player_win_list = player_win_list    			
		pool_info.player_bet_coins = player_bet_coins
		pool_info.player_side_win = self.win_pool_chip[pool_id] 
		pool_info.bet_coins = self:getPoolAllBet(pool_id) --总下注
		pool_info.total_side_win = self.win_pool_total_chip[pool_id] --算上机器人
		pool_info.win = self.win_pool_id[pool_id] or false
		pool_info.bet_coins_commission = player_bet_coins - pool_free_bet --各池真人非免佣下注总和
		pool_info.bet_coins_not_commission = pool_free_bet
		pool_info.side = pool_id
		if pool_id == self.pool_name.player then 
			pool_info.cards = self.player_cards
		elseif pool_id == self.pool_name.banker then 
			pool_info.cards = self.banker_cards
		end
		table_insert(side_list, pool_info)
   	end 
   	local table_gid = os.date("%Y%m%d%H%M%S") .."_".. self.table_id
   	--system_result  	
   	local record = {
		  exinfo = {
		    system_result = self.system_result, --系统控制类型
		    control_uid = self.control_uid or 0, 
		    err_result = self.control_result,
		  },
		  end_time = self.end_time,
		  begin_time = self.start_time,
		  total_num = self.bet_user_num, --参加游戏人数
		  loser_list = self.loser_list,
		  winner_list = self.winner_list,
		  curr_round = self.cur_round,
		  table_gid = table_gid,
		  game_type = self.game_type,
		  address = skynet.address(skynet.self()),
		  table_type = self.table_type,
		  side_list= side_list, --详情
		  op= "card_record",		  
	}
    billlog(record)

    dbglog("___side_list__1111111111111111111___________", record)
end


--库存控制
--1. 系统控制后提出需求 吃或放
--2. 给出一个游戏结果
--3. 计算输赢是否满足需求

	--基础库存
	-- ["fee_rate"] = 1000, --抽水率（百分比
	-- ["base_min"] = 1000000, --库存下限值
	-- ["base_max"] = 10000000, --库存上限值
	-- ["base_normal"] = 5000000, --正常值
	-- ["win_control_rate"] = 5000, --吃分控制率（万分比
	-- ["lose_control_rate"] = 5000, --放分控制率（万分比
	-- ["warn_control_rate"] = 8000, --警戒控制率（万分比
	-- ["base_lose_limit"] = 950000, --库存单局输钱上限
	--奖励库存
	-- ["award_rate"] = 500, --抽水率（百分比
	-- ["award_min"] = 1000000, --库存下限值
	-- ["award_max"] = 10000000, --库存上限值
	-- ["tigger_rate_min"] = 1500, --触发概率下限(万分比)
	-- ["tigger_rate_max"] = 2500, --触发概率上限(万分比)
	-- ["award_lose_limit"] = 5000, --单局输钱上限(元)
	-- ["special_rate_bank_pair"] = 10, --庄对概率(百分比)
	-- ["special_rate_play_pair"] = 10, --闲对概率(百分比)
	-- ["special_rate_tie"] = 10, --和牌概率(百分比)

--跟据库存开出游戏结果
function Desk:getResult()
	--store_result 1系统赢 2、系统输 0、随机
    local store_result, personal_uid = self.store_manager:getSystemStoreResult()
    self.system_result = store_result --系统控制类型
    self.control_uid = personal_uid --gm控制玩家uid
    if not store_result then
        errlog("failed to get store_result",store_result,personal_uid)
        return
    end

    dbglog("system___control__result__",store_result,personal_uid)
	if self.system_result == constant.AWARD_STORE_LOSE then --系统输
		self.system_send_award = true --获得奖励库存
	end

    --配置牌
    if self.rule:isPeiPai() then 
    	self.player_cards, self.banker_cards = self.rule:getCards()
    	return
    end
    --给出一个游戏结果
    local cards_res = {}
    local tie_cards = {} --和的牌
	local pairs_cards = {} --对子牌       
    --开1闲 2和 3庄
    for i=1, 3 do
	    local player_cards, banker_cards = self.rule:getWantCard2(i) --开指定池得到相应的牌	    	    
	    local check_pass = self:checkResult(player_cards, banker_cards)
	    if check_pass then 	    
	    	if i == self.pool_name.tie then 
	    		tie_cards = {player_cards, banker_cards}
	    	else		    	
		    	table_insert(cards_res, {player_cards, banker_cards})	
	    	end	
	    end		
	    local player_cards, banker_cards = self.rule:getPairCards(i)
	    local check_pass = self:checkResult(player_cards, banker_cards)
	    if check_pass then 
	    	table_insert(pairs_cards, {player_cards, banker_cards})	
	    end
	end
	--有真人下注再控制和
	local users = self.user_manager:getRealBetUsers()
	if next(users) then 
		--开和的概率（在robot_store.lua里有配置
		local robot_store = self.room_config:getRobotStore()
		local special_rate_tie = robot_store.special_rate_tie or 0
		local num = math_random(1,100)
		if next(tie_cards) and  (num < special_rate_tie or not next(cards_res)) then 
			self.player_cards = tie_cards[1]
			self.banker_cards = tie_cards[2]
			return 
		end
	else
		if next(tie_cards) and math_random(1, 7) == 1 then --1/5概率加上和
			table_insert(cards_res, tie_cards)
		end
	end
	if not next(cards_res) then 
		cards_res = pairs_cards
	end
	if next(cards_res) then 
		local index = math_random(1, #cards_res)
		local res = cards_res[index]
		self.player_cards = res[1]
		self.banker_cards = res[2]
		self.control_result = 0  --系统控制结果 0控制成功 1系统赢钱 2随机
		return 
	end
	if self.control_result == 1 then --控制结果不满足需求
		--杀	    
	    self.system_result = constant.SYSTEM_STORE_WIN --库存1赢钱 
	    if self.control_uid then 
	    	self.system_result = constant.PERSONAL_STORE_LOSE
	    end
	    local check_pass = false
	    --开1闲 2和 3庄
	    for i=1, 3 do
		    local player_cards, banker_cards = self.rule:getWantCard2(i) --开指定池得到相应的牌	    	    
		    check_pass = self:checkResult(player_cards, banker_cards)
		    if check_pass then 	    
				self.player_cards = player_cards
				self.banker_cards = banker_cards 		
				break
		    end				    
		end		
		if check_pass then 
			return 
		end
		self.control_result = 2 --杀不住
		self.system_result = constant.SYSTEM_NO_CONTROL --随机 
	end
	dbglog("------baijiale无法满足条件随机出结果----------")
	--随机
	self.player_cards, self.banker_cards = self.rule:getPlayAndBankCards()
end

--检查结果是否符合库存
function Desk:checkResult(player_cards, banker_cards)
    
    local robot_store = self.room_config:getRobotStore()    
    local lose_limit = robot_store.base_lose_limit or 100000 --库存单局输钱上限
    if self.system_result == constant.AWARD_STORE_LOSE then
        lose_limit = robot_store.award_lose_limit or 100000
    end

    local bet_coins = self.real_bet_chip --总下注额
    local real_pool_bet = self.real_pool_bet --各池真人下注总额
    if self.control_uid then --对个人控制
    	bet_coins = self:getUserBet(self.control_uid)
    	real_pool_bet = {}
    	for pool_id=1, self.max_pool_id do
    		real_pool_bet[pool_id] = self:getPoolUserBet(pool_id, self.control_uid)
    	end
    end
    local win_pools = {} --各池结果
	--大小结果
	local win_id = self.rule:compareCard(player_cards, banker_cards)
	win_pools[win_id] = true
	if self.rule:existPair(player_cards) then --闲对子
		win_pools[self.pool_name.player_pairs] = true
	end
	if self.rule:existPair(banker_cards) then  --庄对子
		win_pools[self.pool_name.banker_pairs] = true
	end   
    local award_list = {} 
    local win_chip = 0 --玩家总的赢钱
    for pool_id=1, self.max_pool_id do 
    	if win_pools[pool_id] then 
	        local award_coins = real_pool_bet[pool_id] * (1 + self.pool_rate[pool_id])
	        win_chip = win_chip + award_coins
	    end
    end
    if win_id == self.pool_name.tie then --开和
    	win_chip = win_chip + self.real_pool_bet[self.pool_name.player]
    	win_chip = win_chip + self.real_pool_bet[self.pool_name.banker]
    end
    win_chip = win_chip - bet_coins
    
    dbglog("______self.system_result_______", self.system_result, win_chip)
    dbglog("___________result___",win_id,win_pools[4],win_pools[5], bet_coins, lose_limit)
    if win_chip > lose_limit then --是否超过系统输钱上限， 这个游戏结果不通过
    	self.control_result = 1  --系统控制结果 0控制成功 1系统赢钱 2随机
    	errlog("___baijiale___over__lose_limit___", self.system_result, win_chip, lose_limit)
    	return false
    end
    if self.system_result == constant.SYSTEM_NO_CONTROL then --随机时才放到结果里
    	return true
    end
    if win_chip < 0 then 
    	--系统赢
    	if self.system_result == constant.SYSTEM_STORE_WIN then --系统赢    		
    		return true
    	end
    	if self.system_result == constant.PERSONAL_STORE_LOSE then 
    		return true
    	end      	
    elseif win_chip > 0 then 
    	--系统输
    	if self.system_result == constant.AWARD_STORE_LOSE then --系统输
    		return true
    	end
    	if self.system_result == constant.SYSTEM_STORE_LOSE then --系统输    		
    		return true
    	end
    	if self.system_result == constant.PERSONAL_STORE_WIN then --    		
    		return true
    	end     
    else
    	        		
    end
    return false
end

--库存处理
function Desk:updateStore()
	local gm_store_coins = 0 --个人控制结果金币的输赢
	--更新个人库存
	if self.control_uid and self.win_chip_list[self.control_uid] then 
		self.control_coins = self.win_chip_list[self.control_uid]
		gm_store_coins = self.store_manager:updatePersionStore(self.system_money_cost, self.control_coins, self.control_uid, self.system_result )
	end
	--更新系统库存
	self.store_manager:updateSystemStore(self.system_money_cost - gm_store_coins, self.system_send_award)
	dbglog("________updateSystemStore_________", self.system_money_cost, gm_store_coins ,self.system_send_award, self.control_uid, self.system_result )
	if not self.system_send_award or self.control_result ~= 0 then
		--更新抽水库存,奖励库
		self.store_manager:updateRobotStore(math_abs(self.system_money_cost) - math_abs(gm_store_coins))
	end	
	self.store_manager:checkStoreTransfer()
end



return Desk